﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SergeyPravodelov.Practice.BookStore.Data.Services;
using SergeyPravodelov.Practice.BookStore.Models;

namespace SergeyPravodelov.Practice.BookStore.Controllers
{
    public class BookController : Controller
    {
        public IDataService Storage
        {
            get { return BookStoreMvcApplication.DataContext.Get<IDataService>(); }
        }

        //
        // GET: /book/list
        [HttpGet]
        public ActionResult List()
        {
            return Json(Storage.GetData().Cast<Book>().Select(book => new
            {
                id = book.Id,
                title = book.Title,
                authors = book.Authors,
                isbn = book.ISBN,
                pages = book.Pages,
                publisher = book.Publisher,
                year = book.Year
            }), JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /book/get/:id
        [HttpGet]
        public ActionResult Get(int id)
        {
            var book = (Book) Storage.GetData(id);
            return Json(new
            {
                id = book.Id,
                title = book.Title,
                authors = book.Authors,
                isbn = book.ISBN,
                pages = book.Pages,
                publisher = book.Publisher,
                year = book.Year
            }, JsonRequestBehavior.AllowGet);
        }

        //
        // POST: /book/add
        [HttpPost]
        public ActionResult Add(List<Book> book)
        {
            if (ModelState.IsValid)
            {
                return Json(Storage.PutData(book));
            }
            Response.StatusCode = 422;
            return Json(ModelState.Values.Where(m => m.Errors.Count > 0)
                .Select(ms => ms.Errors.Select(e => e.ErrorMessage)));
        }

        //
        // PUT: /book/modify
        [HttpPut]
        public ActionResult Modify(Book book)
        {
            if (ModelState.IsValid)
            {
                Storage.ModifyData(book);
                return Json(new[]{book.Id});
            }
            Response.StatusCode = 422;
            return Json ( ModelState.Values.Where ( m => m.Errors.Count > 0 )
                .Select ( ms => ms.Errors.Select ( e => e.ErrorMessage ) ) );
        }

        //
        // DELETE: /book/delete/:id
        [HttpDelete]
        public ActionResult Delete(int id)
        {
            Storage.RemoveData(id);
            return new EmptyResult();
        }

        //
        // GET: /book/image/:id
        [AcceptVerbs(HttpVerbs.Get)]
        [OutputCache ( NoStore = true , Duration = 0 , VaryByParam = "None" )]
        public ActionResult Image(int? id)
        {
            if (id.HasValue)
            {
                var book = (Book) Storage.GetData(id.Value);
                if (book != null)
                {
                    if (book.ImageBitmap == null || book.ImageBitmap.Length == 0)
                    {
                        return new FileContentResult(Book.DefaultImage, "image/png");
                    }
                    return new FileContentResult(book.ImageBitmap, "image/jpeg");
                }
                Response.StatusCode = 404;
            }
            return new EmptyResult();
        }

        [HttpPost]
        public ActionResult Image(HttpPostedFileBase file)
        {
            if (file != null)
            {
                int bookId;
                if (!int.TryParse(Request.QueryString["book"], out bookId))
                {
                    Response.StatusCode = 404;
                }
                var book = (Book) Storage.GetData(bookId);
                if (book != null)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        file.InputStream.CopyTo(memoryStream);
                        book.ImageBitmap = memoryStream.GetBuffer();
                    }
                    Storage.ModifyData(book);
                }
                else
                {
                    Response.StatusCode = 404;
                }
            }
            return new EmptyResult();
        }
    }
}